using System;
using Unity.Mathematics;
using UnityEngine;

namespace Gj
{
    public class ScreenHandle : MonoBehaviour
    {

        public enum HandleMode
        {
            None,
            Simple,
            Complex
        }

        public enum HandleAction
        {
            None,
            ThreeTouchUp,
            ThreeTouchDown
        }

        public int mouseIndexSimple = 0;
        public int mouseIndexComplex = 2;
        public float boundarySpeed = 1;
        public float Speed = 1;
        private Vector2 deltaPos = Vector2.zero;

        private float moveTime;
        private bool moving;
        private Vector2 oldPosition = Vector2.zero;

        private Touch oldTouch1; //上次触摸点1(手指1)
        private Touch oldTouch2; //上次触摸点2(手指2)
        private readonly float pre = 10;
        private float waitTime = 1;

        public float touchThreshold = 10;
        public float touchRatio = 100;
        private float touchTmp = 0;
        
        private Vector2[] touchStartPositions = new Vector2[3];
        private Vector2[] touchEndPositions = new Vector2[3];
        private float[] touchStartTimes = new float[3];

        private float swipeThreshold = 50f;  // 滑动的最小距离（可以根据需要调整）
        private bool isSwipeUp = false;
        private bool isSwipeDown = false;

        public bool move;
        public int moveIndex;
        public bool scale;
        public bool boundary;
        public bool drag;

        public HandleMode mode = HandleMode.Simple;

        // Update is called once per frame
        public void Handle()
        {
            HandleSimple();
            // switch(mode)
            // {
            //     case HandleMode.Simple:
            //     HandleSimple();
            //     break;
            //     case HandleMode.Complex:
            //     HandleComplex();
            //     break;
            // }
        }
        
        private void CheckHandleAction()
        {
            SystemInput.handle = HandleAction.None;
            if (Input.touchCount == 3) // 确保有三个触摸点
            {
                // 记录每个触摸点的初始位置和时间
                for (int i = 0; i < 3; i++)
                {
                    if (Input.GetTouch(i).phase == TouchPhase.Began)
                    {
                        touchStartPositions[i] = Input.GetTouch(i).position;
                        touchStartTimes[i] = Time.time;
                    }
                }

                // 检查每个触摸点的滑动方向
                isSwipeUp = true;
                isSwipeDown = true;

                for (int i = 0; i < 3; i++)
                {
                    touchEndPositions[i] = Input.GetTouch(i).position;

                    float verticalMovement = touchEndPositions[i].y - touchStartPositions[i].y;
                    float timeElapsed = Time.time - touchStartTimes[i];

                    // 如果滑动的距离小于阈值，则不认为是有效的滑动
                    if (Mathf.Abs(verticalMovement) < swipeThreshold)
                    {
                        isSwipeUp = false;
                        isSwipeDown = false;
                        break;
                    }

                    // 根据触摸点的滑动方向判断是否为向上滑动或向下滑动
                    if (verticalMovement > 0)  // 向上滑动
                    {
                        isSwipeDown = false;
                    }
                    else if (verticalMovement < 0)  // 向下滑动
                    {
                        isSwipeUp = false;
                    }
                }

                // 判断是向上还是向下滑动
                if (isSwipeUp)
                {
                    SystemInput.handle = HandleAction.ThreeTouchUp;
                }
                else if (isSwipeDown)
                {
                    SystemInput.handle = HandleAction.ThreeTouchDown;
                }
            }

        }

        private void HandleComplex()
        {
            if (moving && !Input.GetMouseButton(mouseIndexComplex) && Input.touchCount == 0)
            {
                SystemInput.sm = false;
                moving = false;
                // if (Time.time < moveTime + waitTime)
                // {
                //     deltaPos = new Vector2(deltaPos.x - deltaPos.x / pre / waitTime,
                //         deltaPos.y - deltaPos.y / pre / waitTime);
                //     SystemInput.sx = deltaPos.x;
                //     SystemInput.sy = deltaPos.y;
                // }
                // else if (Time.time > moveTime + waitTime)
                // {
                //     SystemInput.sm = false;
                //     moving = false;
                //     Emit(UIEvent.End);
                // }
            }

            SystemInput.si = 0;

            if (Game.GetDevicePlatform() == "PC")
            {
                if (move)
                {
                    if (Input.GetMouseButtonDown(mouseIndexComplex))
                    {
                        SystemInput.sx = 0;
                        SystemInput.sy = 0;
                        deltaPos = Vector2.zero;
                        SystemInput.sm = true;
                        moving = true;
                        oldPosition = Vector2.zero;
                    }

                    if (moving && Input.GetMouseButton(mouseIndexComplex))
                    {
                        Vector2 newPosition = Input.mousePosition;
                        if (oldPosition != Vector2.zero)
                        {
                            deltaPos = newPosition - oldPosition;
                            SystemInput.sx = deltaPos.x;
                            SystemInput.sy = deltaPos.y;
                            // waitTime = (Math.Abs(deltaPos.x) + Math.Abs(deltaPos.y)) / 4;
                            moveTime = Time.time;
                        }

                        oldPosition = newPosition;
                    }
                }

                if (scale && Input.mouseScrollDelta != Vector2.zero) SystemInput.si = Input.mouseScrollDelta.y;
                
                if (boundary) BoundaryHandle(Input.mousePosition);
            }

            //没有触摸
            if (Input.touchCount <= 0) return;

            if (Input.touchCount == 1)
            {
                if (!move && boundary) BoundaryHandle(Input.GetTouch(0).position);
            }
            if (Input.touchCount == 2)
            {
                if (move)
                {
                    //多点触摸, 放大缩小
                    var newTouch1 = Input.GetTouch(0);
                    var newTouch2 = Input.GetTouch(1);

                    //第2点刚开始接触屏幕, 只记录，不做处理
                    if (moving == false)
                    {
                        oldTouch2 = newTouch2;
                        oldTouch1 = newTouch1;
                        SystemInput.sx = 0;
                        SystemInput.sy = 0;
                        deltaPos = Vector2.zero;
                        SystemInput.sm = true;
                        moving = true;
                        return;
                    }

                    if (newTouch1.phase == TouchPhase.Moved || newTouch2.phase == TouchPhase.Moved)
                    {
                        //计算老的两点距离和新的两点间距离，变大要放大模型，变小要缩放模型
                        var oldDistance = Vector2.Distance(oldTouch1.position, oldTouch2.position);
                        var newDistance = Vector2.Distance(newTouch1.position, newTouch2.position);

                        //两个距离之差，为正表示放大手势， 为负表示缩小手势
                        var offset = newDistance - oldDistance;

                        if (math.abs(offset) > touchThreshold)
                        {
                            //放大因子， 一个像素按 0.01倍来算(100可调整)
                            SystemInput.si = offset / touchRatio;
                        }
                        else
                        {
                            // Debug.LogError(deltaPos);
                            //单点触摸， 水平上下旋转
                            deltaPos = Input.GetTouch(0).deltaPosition / 2;
                            SystemInput.sx = deltaPos.x;
                            SystemInput.sy = deltaPos.y;
                            // waitTime = (Math.Abs(deltaPos.x) + Math.Abs(deltaPos.y)) / 4;
                            moveTime = Time.time;
                        }
                    }
                    //记住最新的触摸点，下次使用
                    oldTouch1 = newTouch1;
                    oldTouch2 = newTouch2;
                }
            }
        }

        private void HandleSimple()
        {

                        
#if UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX || UNITY_EDITOR
            HandlePc();
#elif UNITY_IPHONE || UNITY_ANDROID
            HandleMobile();
#else
            HandleMobile();
#endif
        }

        private void HandlePc()
        {

            SystemInput.si = 0;
            SystemInput.sr = 0;

            if (drag && Input.GetMouseButtonDown(0))
            {
                SystemInput.sm = true;
                oldPosition = Input.mousePosition;
                // Debug.LogErrorFormat("GetMouseButtonDown: {0}", oldPosition);
            }

            if (drag && Input.GetMouseButtonUp(0))
            {
                SystemInput.sm = false;
            }

            if (drag && Input.GetMouseButton(0))
            {
                Vector2 newPosition = Input.mousePosition;
                // Debug.LogErrorFormat("GetMouseButton: {0} {1}", oldPosition, newPosition);
                deltaPos = newPosition - oldPosition;
                SystemInput.sx = deltaPos.x;
                SystemInput.sy = deltaPos.y;
                oldPosition = newPosition;
            }

            // 右键旋转处理
            if (Input.GetMouseButtonDown(1))
            {
                oldPosition = Input.mousePosition;
            }

            if (Input.GetMouseButton(1))
            {
                Vector2 newPosition = Input.mousePosition;
                Vector2 rotateDelta = newPosition - oldPosition;

                // 水平移动转换为旋转角度，可以根据需要调整灵敏度
                float angleDelta = rotateDelta.x * 0.5f;
                SystemInput.sr = angleDelta;

                oldPosition = newPosition;
            }

            if (!drag)
            {
                SystemInput.sx = 0;
                SystemInput.sy = 0;
                if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow)) SystemInput.sy -= Speed;
                if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow)) SystemInput.sy += Speed;
                if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow)) SystemInput.sx -= Speed;
                if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow)) SystemInput.sx += Speed;

                if (SystemInput.sx != 0 || SystemInput.sy != 0)
                {
                    SystemInput.sm = true;
                }
                else
                {
                    SystemInput.sm = false;
                }
            }

            if (scale && Input.mouseScrollDelta != Vector2.zero) SystemInput.si = Input.mouseScrollDelta.y;

            if (boundary) BoundaryHandle(Input.mousePosition);
            if (!boundary && SystemInput.sb)
            {
                SystemInput.bx = 0;
                SystemInput.by = 0;
                SystemInput.sb = false;
            }
        }

        private void HandleMobile()
        {
            if (!boundary && SystemInput.sb)
            {
                SystemInput.bx = 0;
                SystemInput.by = 0;
                SystemInput.sb = false;
            }
            
            if (!SystemInput.sm)
            {
                if (move)
                {
                    SystemInput.sm = true;
                    SystemInput.sx = 0;
                    SystemInput.sy = 0;
                    deltaPos = Vector2.zero;
                    oldPosition = Vector2.zero;
                }
            }
            else if (SystemInput.sm)
            {
                if (!move)
                {
                    SystemInput.sm = false;
                }
            }

            SystemInput.si = 0;
            //没有触摸
            if (Input.touchCount <= 0) return;

            if (Input.touchCount == 1)
            {
                if (!move && boundary) BoundaryHandle(Input.GetTouch(0).position);
            }

            if (Input.GetTouch(0).phase == TouchPhase.Began)
            {
                SystemInput.sx = 0;
                SystemInput.sy = 0;
                deltaPos = Vector2.zero;
            }

            if (move && Input.touchCount == 1)
            {
                deltaPos = Input.GetTouch(0).deltaPosition / 2;
                SystemInput.sx = deltaPos.x;
                SystemInput.sy = deltaPos.y;
            }

            if (move && Input.touchCount == 2)
            {
                deltaPos = Input.GetTouch(moveIndex).deltaPosition / 2;
                SystemInput.sx = deltaPos.x;
                SystemInput.sy = deltaPos.y;
            }

            if (scale && Input.touchCount == 2)
            {
                SystemInput.sm = false;
                SystemInput.si = 0;
                SystemInput.sr = 0;
                //多点触摸, 放大缩小
                var newTouch1 = Input.GetTouch(0);
                var newTouch2 = Input.GetTouch(1);

                //第2点刚开始接触屏幕, 只记录，不做处理
                if (newTouch2.phase == TouchPhase.Began)
                {
                    oldTouch2 = newTouch2;
                    oldTouch1 = newTouch1;
                    return;
                }

                if (newTouch1.phase == TouchPhase.Moved || newTouch2.phase == TouchPhase.Moved)
                {
                    //计算老的两点距离和新的两点间距离，变大要放大模型，变小要缩放模型
                    var oldDistance = Vector2.Distance(oldTouch1.position, oldTouch2.position);
                    var newDistance = Vector2.Distance(newTouch1.position, newTouch2.position);

                    //两个距离之差，为正表示放大手势， 为负表示缩小手势
                    var offset = newDistance - oldDistance;

                    // 缩放判断：2指分开放大，2指靠拢缩小
                    // 距离变化超过阈值才认为是缩放，避免旋转时的微小距离波动
                    float scaleThreshold = 5f; // 距离变化阈值（像素）

                    if (Mathf.Abs(offset) > scaleThreshold)
                    {
                        //放大因子， 一个像素按 0.01倍来算(100可调整)
                        SystemInput.si = offset / touchRatio;
                    }

                    // 计算旋转角度
                    // 计算旧的两点向量角度
                    Vector2 oldVector = oldTouch2.position - oldTouch1.position;
                    float oldAngle = Mathf.Atan2(oldVector.y, oldVector.x) * Mathf.Rad2Deg;

                    // 计算新的两点向量角度
                    Vector2 newVector = newTouch2.position - newTouch1.position;
                    float newAngle = Mathf.Atan2(newVector.y, newVector.x) * Mathf.Rad2Deg;

                    // 计算角度差（旋转增量）
                    float angleDelta = newAngle - oldAngle;

                    // 处理角度跨越 -180/180 边界的情况
                    if (angleDelta > 180f)
                        angleDelta -= 360f;
                    else if (angleDelta < -180f)
                        angleDelta += 360f;

                    SystemInput.sr = angleDelta;

                    // SystemInput.si = offset / touchRatio + touchTmp;
                    // touchTmp = 0;
                    // if (math.abs(SystemInput.si) < 1)
                    // {
                    //     touchTmp = SystemInput.si;
                    //     SystemInput.si = 0;
                    // }
                }

                //记住最新的触摸点，下次使用
                oldTouch1 = newTouch1;
                oldTouch2 = newTouch2;
            }
        }

        private void BoundaryHandle(Vector2 p)
        {
            if (IsBoundary(p))
            {
                var b = (SystemInput.screenCenter - p).normalized;
                SystemInput.bx = b.x * boundarySpeed;
                SystemInput.by = b.y * boundarySpeed;
                SystemInput.sb = true;
            }
            else
            {
                SystemInput.bx = 0;
                SystemInput.by = 0;
                SystemInput.sb = false;
            }
        }

        private bool IsBoundary(Vector2 p)
        {
            // if (p.x < 0 || p.y < 0 || p.x > SystemInput.screenSize.x || p.y > SystemInput.screenSize.y) return false;
            // Debug.LogErrorFormat("IsBoundary: {0} {1} {2} {3}", p, SystemInput.screenMin, SystemInput.screenMax, p.x < SystemInput.screenMin.x || p.y < SystemInput.screenMin.y || p.x > SystemInput.screenMax.x ||
                // p.y > SystemInput.screenMax.y);
            if (p.x < SystemInput.screenMin.x || p.y < SystemInput.screenMin.y || p.x > SystemInput.screenMax.x ||
                p.y > SystemInput.screenMax.y)
                return true;

            return false;
        }
    }
}